import { Color, Matrix4, Vector3, Quaternion } from 'https://unpkg.com/three/build/three.module.js';
import { initShaders, ScaleLinear } from '../jsm/Utils.js';
import lib from '../jsm/ThreeLib.js';
import Poly from '../jsm/Poly.js'
import Sky from '../jsm/Sky.js'
import ShapeGeo from '../jsm/ShapeGeo.js';
import Ground2D from '../jsm/Ground2D.js'

window.onload = function () {

    const backColor = new Color("rgba(0,0,0,1)");

    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    const gl = canvas.getContext("webgl");
    //开启颜色合成,才会有透明度的感觉
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

    //初始化着色器
    initShaders(gl,
        document.querySelector("#vertexShader").innerText,
        document.querySelector("#fragmentShader").innerText);
    lib.clearCanvas(gl, new Color("rgba(0,0,0,1)"), 1);


    const endLength = 100;
    const interval = 2;
    const nodeCount = (endLength / interval + 1) * (endLength / interval + 1);



    /* x,z 方向的空间坐标极值 */
    const [minPosX, maxPosX, minPosZ, maxPosZ] = [
        -0.9, 0.9, -0.9, 0.9
    ]
    /* x,z 方向的弧度极值 */
    const [minAngX, maxAngX, minAngZ, maxAngZ] = [
        0, Math.PI * 4, 0, Math.PI * 2
    ]

    /* 比例尺：将空间坐标和弧度相映射 */
    const scalerX = ScaleLinear(minPosX, minAngX, maxPosX, maxAngX)
    const scalerZ = ScaleLinear(minPosZ, minAngZ, maxPosZ, maxAngZ)

    const glArr = cssToGl(createNodes(), maxPosX);


    let poly = new Poly({
        gl: gl,
        vertices: glArr,
        size: 3,
        pointSize: 3,
    })


    var vm4 = new Matrix4().lookAt(
        new Vector3(0.2, 0.5, 1),
        new Vector3(0, 0, 0),
        new Vector3(0, 1, 0),
    );
    var mm4 = new Matrix4();
    mm4.makeRotationY(0.5);


    let u_Vm4 = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
    gl.uniformMatrix4fv(u_Vm4, false, vm4.elements);

    let u_Mm4 = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
    gl.uniformMatrix4fv(u_Mm4, false, mm4.elements);


    updateY();
    poly.updateBuffer();
    poly.draw(["POINTS"]);


    let offset = 0;
    (function ani() {
        offset += 0.02
        updateY(offset)
        poly.updateBuffer()
        poly.draw(["POINTS"]);
        requestAnimationFrame(ani);
    })();




    function updateY(offset = 0) {
        for (let i = 0; i < glArr.length; i += 3) {
            const [x, z] = [glArr[i], glArr[i + 2]];
            const angZ = scalerZ(z);
            const Omega = 2;
            const a = Math.sin(angZ) * 0.1 + 0.03;
            const phi = scalerX(x) + offset;
            glArr[i + 1] = SinFn(a, Omega, phi)(angZ);
        }
    }

    function SinFn(a, Omega, phi) {
        return function (x) {
            return a * Math.sin(Omega * x + phi);
        }
    }

    function createNodes() {
        let arr = [];
        let [x, y, z] = [0, 0, 0];
        for (let i = 0; i < nodeCount; i++) {
            arr.push(x, y, z);
            x += interval;
            if (x > endLength) {
                x = 0;
                z += interval;
            }
        }
        return arr;
    }

    function cssToGl(arr, glpos) {
        const glInterval = interval / endLength * gl;
        let tempArr = [];

        for (let i = 0; i < arr.length; i += 3) {
            tempArr.push((arr[i] / endLength) * (glpos * 2) - glpos);
            tempArr.push(arr[i + 1]);
            tempArr.push((arr[i + 2] / endLength) * (glpos * 2) - glpos);
        }
        return tempArr;
    }


}